//
// GPSMapEdit
// (c) Konstantin Galichsky (kg@geopainting.com), 2005
//
// Device-independent bitmap (24-bit RGB).
//

# include "StdAfx.h"
# include "DIBitmap.h"

CDIBitmap::CDIBitmap (long _lWidth, long _lHeight) :
	CBitmap (_lWidth, _lHeight > 0 ? _lHeight : -_lHeight),
	m_pBits (NULL)
{
	::memset (& m_BitmapInfo, 0, sizeof (BITMAPINFOHEADER));
	m_BitmapInfo.biSize = sizeof (BITMAPINFOHEADER);
	m_BitmapInfo.biWidth       = _lWidth;
	m_BitmapInfo.biHeight      = _lHeight;
	m_BitmapInfo.biPlanes      = 1;
	m_BitmapInfo.biBitCount    = 24;
	m_BitmapInfo.biCompression = BI_RGB;

	const size_t cBytes = GetScanWidth ()*m_lHeight;
	m_pBits = new BYTE [cBytes];
//	::memset (m_pBits, 0x00, cBytes);
}

CBitmap * CDIBitmap::MakeSmall () const {
	CDIBitmap * const pBitmap = new CDIBitmap (m_lWidth/2, m_BitmapInfo.biHeight/2);
	if (pBitmap->GetBits () == NULL) {
		delete pBitmap;
		return NULL;
	}
	BYTE * const pBits_Dst = pBitmap->GetBits ();

	const int nScanWidth_Src = GetScanWidth ();
	const int nScanWidth_Dst = pBitmap->GetScanWidth ();

	for (int y = 0; y < m_lHeight/2; ++ y) {
		const BYTE * const pScan_Src0 = m_pBits   + y*nScanWidth_Src*2;
		const BYTE * const pScan_Src1 = pScan_Src0 + nScanWidth_Src;
		      BYTE * const pScan_Dst  = pBits_Dst + y*nScanWidth_Dst;

		for (int x = 0; x < m_lWidth/2; ++ x) {
			const BYTE * const pPixel_Src00 = pScan_Src0 + x*3*2;
			const BYTE * const pPixel_Src10 = pScan_Src1 + x*3*2;
			const BYTE * const pPixel_Src01 = pPixel_Src00 + 3;
			const BYTE * const pPixel_Src11 = pPixel_Src10 + 3;

			assert (x*2 < m_lWidth);
			assert (y*2 < m_lHeight);

			BYTE * const pPixel_Dst = pScan_Dst + x*3;

			pPixel_Dst [0] = (WORD (pPixel_Src00 [0]) + pPixel_Src10 [0] + pPixel_Src01 [0] + pPixel_Src11 [0])/4;
			pPixel_Dst [1] = (WORD (pPixel_Src00 [1]) + pPixel_Src10 [1] + pPixel_Src01 [1] + pPixel_Src11 [1])/4;
			pPixel_Dst [2] = (WORD (pPixel_Src00 [2]) + pPixel_Src10 [2] + pPixel_Src01 [2] + pPixel_Src11 [2])/4;
		}
	}

	return pBitmap;
}

# include "DDBitmap.h"

BOOL CDIBitmap::AlphaBlend (
	HDC _hdcDest,
	int _xDest, int _yDest, int _wDest, int _hDest,
	int _xSrc,  int _ySrc,  int _wSrc,  int _hSrc,
	BYTE _SourceConstantAlpha
) const {
	CDDBitmap ddb (_wSrc, _hSrc);
	if (ddb.GetBitmap () == NULL)
		return FALSE;

	const int h = GetBitmapInfo ()->bmiHeader.biHeight;

	::SetDIBitsToDevice (
		ddb.GetDC (),
		0, 0, _wSrc, _hSrc,
		_xSrc, h - _hSrc, _ySrc, h - _ySrc,
//		_xSrc, h - _hSrc - _ySrc, 0, h - _ySrc,
		m_pBits, GetBitmapInfo (), DIB_RGB_COLORS
	);

	return ddb.AlphaBlend (_hdcDest, _xDest, _yDest, _wDest, _hDest, 0, 0, _wSrc, _hSrc, _SourceConstantAlpha);
}

